package cdu.sl.service.impl;

import cdu.sl.annotation.KeyAction;
import cdu.sl.dto.SaveUserDTO;
import cdu.sl.dto.UserSignupDTO;
import cdu.sl.entity.UserRole;
import cdu.sl.enumeration.UserRoleEnum;
import cdu.sl.mapper.UserDao;
import cdu.sl.entity.User;
import cdu.sl.enumeration.KeyActionType;
import cdu.sl.mapper.UserRolesDao;
import cdu.sl.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserDao userDao;

    private final HttpServletRequest httpServletRequest;

    private final PasswordEncoder passwordEncoder;

    private final UserRolesDao userRolesDao;


//    /**
//     * 登录
//     *
//     * @param userLoginDTO 登录提交的表单数据
//     * @return 用户信息
//     */
//    @Override
//    @KeyAction(KeyActionType.LOGIN)
//    public User login(UserLoginDTO userLoginDTO) {
//        User user = userDao.findByUsernameAndPassword(userLoginDTO.getUsername(), userLoginDTO.getPassword());
//        if (user == null) return null;
//        // 将用户信息保存到会话范围
//        HttpSession session = httpServletRequest.getSession();
//        session.setAttribute("userInfo", user);
//        return user;
//    }

    /**
     * 注销
     */
    @Override
    @KeyAction(KeyActionType.LOGOUT)
    public void logout() {
        HttpSession session = httpServletRequest.getSession();
        session.invalidate();
    }

    /**
     * 注册
     *
     * @param userSignupDTO 注册
     */
    @Override
    public void signup(UserSignupDTO userSignupDTO) {
        // 验证用户是否存在
        User isPresent = userDao.findByUsername(userSignupDTO.getUsername());
        log.info("用户data：{}", isPresent);
        if (isPresent != null) throw new DuplicateKeyException("用户名已存在！");

        // 加密密码并保存
        User user = new User();
        String encodePassword = passwordEncoder.encode(userSignupDTO.getPassword());
        user.setUsername(userSignupDTO.getUsername());
        user.setPassword(encodePassword);
        userDao.save(user);

        // todo 分配默认角色和默认权限
        // 默认分配USER角色 -> 只具备访问权限
        UserRole userRole = new UserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(UserRoleEnum.USER.ordinal());
        userRolesDao.save(userRole);
    }

    /**
     * 新增用户
     *
     * @param saveUserDTO 新增用户信息
     */
    @Override
    @Transactional
    public void add(SaveUserDTO saveUserDTO) {
        saveUserInfo(saveUserDTO);
    }

    /**
     * 根据id删除用户
     *
     * @param id 用户id
     */
    @Override
    public void delete(Integer id) {
        userDao.deleteById(id);
    }

    /**
     * 获取所有用户信息
     */
    @Override
    public List<User> findAll() {
        return userDao.findAll()
                .stream()
                .peek(user -> user.setPassword("******")).collect(Collectors.toList());
    }

    /**
     * 根据id获取用户详情
     *
     * @param id 用户id
     * @return 用户信息详情
     */
    @Override
    public User getById(Integer id) {
        Optional<User> opt = userDao.findById(id);
        if (opt.isPresent()) {
            opt.get().setPassword("******");
            return opt.get();
        }
        return null;
    }

    /**
     * 修改用户信息
     *
     * @param saveUserDTO 用户信息实体
     */
    @Override
    public void update(SaveUserDTO saveUserDTO) {
        saveUserInfo(saveUserDTO);
    }


    /**
     * 保存用户信息
     *
     * @param saveUserDTO 用户信息实体
     */
    private void saveUserInfo(SaveUserDTO saveUserDTO) {
        // 获取用户基本信息
        User user = new User();
        BeanUtils.copyProperties(saveUserDTO, user);
        // 如果密码为空 , 说明是新增用户
        if (saveUserDTO.getId() == null) {
            String encodePassword = passwordEncoder.encode(saveUserDTO.getPassword());
            user.setPassword(encodePassword);
        } else {
            Optional<User> opt = userDao.findById(saveUserDTO.getId());
            opt.ifPresent(value -> user.setPassword(value.getPassword()));
        }

        // 保存基本信息
        userDao.save(user);
        // id不为空 ，修改用户角色信息
        List<Integer> userRoleIds=saveUserDTO.getRoleIds();
        for (Integer userRoleId : userRoleIds) {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(userRoleId);
            userRolesDao.save(userRole);
        }


    }


}
